package com.sparrow.common.tick;

import com.sparrow.common.tick.def.Tickable;
import org.springframework.beans.factory.DisposableBean;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 游戏循环ticker
 */
public class GameLoop implements Runnable, DisposableBean {

    private final List<Tickable> tickableList = new CopyOnWriteArrayList<>();
    private volatile boolean running = true;

    public GameLoop() {
    }

    public void addTickable(Tickable tickable) {
        this.tickableList.add(tickable);
    }

    @Override
    public void run() {
            try {
                long last = System.currentTimeMillis();
                long frameTime = 1000 / 60;
                while (running) {
//                    System.out.println("tick");
                    long now = System.currentTimeMillis();
                    long delta = now - last;
                    last = now;

                    for (Tickable component : tickableList) {
                        try {
                            component.tick(now, delta);
                        } catch (Throwable t) {
                            t.printStackTrace();
                        }
                    }

                    long cost = System.currentTimeMillis() - now;
                    long sleep = frameTime - cost;
                    if (sleep > 0) Thread.sleep(sleep);
                }
            } catch (Throwable t) {
                t.printStackTrace(); // 打印线程全局异常
            }
    }

    public void stop() {
        running = false;
    }

    @Override
    public void destroy() throws Exception {
        stop();
    }
}
